/*
 * 竞态条件
 * 1. 多个线程同时访问共享数据，导致数据不一致
 * 2. 至少有一个指针被用来写入数据
 * 3. 没有同步数据访问的机制
 */

// error[E0499]: cannot borrow `s` as mutable more than once at a time
// ① 不能在同一时间，多次借用“s”作为可变变量
// fn main() {
//     let mut s = String::from("hello");
//     let r1 = &mut s;
//     let r2 = &mut s;
//     println!("{}, {}", r1, r2);
// }

// error[E0425]: cannot find value `r1` in this scope
// ② 离开了作用域，无法访问
// fn main() {
//     let mut s = String::from("hello");
//     {
//         let r1 = &mut s;
//     } // r1 在这里离开了作用域，所以我们完全可以创建一个新的引用
//     let r2 = &mut s;
//     println!("{}, {}", r1, r2);
// }

// error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
// ③ 因为“s”被借用为不可变引用，所以不能再借用“s”作为可变引用
// fn main() {
//     let mut s = String::from("hello");
//     let r1 = &s; // 没问题, s被借用为r1的不可变引用
//     let r2 = &s; // 没问题, s被借用为r2的不可变引用
//     let r3 = &mut s; // s再被借用为r3的可变引用，因此违反了规则
//     println!("{}, {}, and {}", r1, r2, r3);
//     // 不可变借用之后可以在这使用
// }

// ④ 正确
fn main() {
    let mut s = String::from("hello");

    let r1 = &s; // 没问题
    let r2 = &s; // 没问题
    println!("r1 = {}, r2 = {}", r1, r2); // 不可引用被全部使用

    let r3 = &mut s; // 此位置之后 r1 和 r2 不再使用
    println!("r3 = {}", r3);
}

/*
 * 总结
 * 1. 在同一作用域内，同一个数据，只能借用<一次><可变>引用
 * 2. 在同一作用域内，同一个数据，可以借用<一次><可变>引用或者<多次><不可变>引用
 * 3. 在同一作用域内，同一个数据，不能同时被借用为可变引用和不可变引用
 * 4. 在同一作用域内，同一个数据，借用被使用过后，借用次数相应的减少
 */
